import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'dart:io';

/// 图片类型
enum ImageType { network, asset, file }

class CacheNetworkImage extends StatefulWidget {
  final String imageUrl;
  final double? width;
  final double? height;
  final double borderRadius;
  final BoxFit fit;
  final Widget? placeholder;
  final Widget? errorWidget;
  final ImageType imageType;

  const CacheNetworkImage({
    super.key,
    required this.imageUrl,
    this.width,
    this.height,
    this.borderRadius = 0,
    this.fit = BoxFit.cover,
    this.placeholder,
    this.errorWidget,
    this.imageType = ImageType.network,
  });

  @override
  State<CacheNetworkImage> createState() => _CacheNetworkImageState();
}

class _CacheNetworkImageState extends State<CacheNetworkImage> {
  @override
  void didUpdateWidget(covariant CacheNetworkImage oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.imageUrl != widget.imageUrl) {
      setState(() {});
    }
  }

  @override
  Widget build(BuildContext context) {
    Widget imageWidget;
    switch (widget.imageType) {
      case ImageType.asset:
        imageWidget = Image.asset(
          widget.imageUrl,
          width: widget.width,
          height: widget.height,
          fit: widget.fit,
        );
        break;
      case ImageType.file:
        imageWidget = Image.file(
          File(widget.imageUrl),
          width: widget.width,
          height: widget.height,
          fit: widget.fit,
        );
        break;
      case ImageType.network:
        imageWidget = widget.imageUrl.isEmpty
            ? NetworkErrorImage(
                width: widget.width,
                height: widget.height,
              )
            : CachedNetworkImage(
                imageUrl: widget.imageUrl,
                width: widget.width,
                height: widget.height,
                fit: widget.fit,
                placeholder: (context, url) =>
                    widget.placeholder ??
                    Container(
                      width: widget.width,
                      height: widget.height,
                      color: Colors.grey[200],
                    ),
                errorWidget: (context, url, error) =>
                    widget.errorWidget ??
                    NetworkErrorImage(
                      width: widget.width,
                      height: widget.height,
                    ),
              );
        break;
    }
    return ClipRRect(
      borderRadius: BorderRadius.circular(widget.borderRadius),
      child: imageWidget,
    );
  }
}

class NetworkErrorImage extends StatelessWidget {
  final double? width;
  final double? height;
  const NetworkErrorImage(
      {super.key, required this.width, required this.height});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: width,
      height: height,
      color: Colors.grey[300],
      child: const Icon(Icons.broken_image, color: Colors.grey),
    );
  }
}
